#include "smartpipe.h"

namespace sp{

// 用于连接多个Function使其输入输出队列对接
void connect(Function* a, Function* b){
    linkFunctions(a, b);
}

// 用于一个Function连接多个Function
void connectOneToMany(int count, ...){
    va_list ap;
	va_start(ap, count);
    Function* the_one_f = va_arg(ap, Function*);
    for(int i = 0; i < count-1; i++) {
		Function* f = va_arg(ap, Function*);
        connect(the_one_f, f);
	}
    va_end(ap);
}

// 用于多个Function连接一个Function
void connectManyToOne(int count, ...){
    va_list ap;
	va_start(ap, count);
    std::vector<Function*> pre_Qs;
    for(int i = 0; i < count-1; i++) {
		Function* f = va_arg(ap, Function*);
        pre_Qs.push_back(f);
	}
    Function* the_one_f = va_arg(ap, Function*);
    for(auto i : pre_Qs){
        connect(i, the_one_f);
    }
    va_end(ap);
}

// 用于多个Function首尾相连
void connectOneByOne(int count, ...){
    va_list ap;
	va_start(ap, count);
    Function* pre_f = va_arg(ap, Function*);
    for(int i = 0; i < count-1; i++) {
		Function* f = va_arg(ap, Function*);
        connect(pre_f, f);
        pre_f = f;
	}
    va_end(ap);
}

// 新建一个队列，一个扇出多个
void connectOneFanMany(int count, ...){
    va_list ap;
	va_start(ap, count);
    BlockingQueue<Data*>* q = new BlockingQueue<Data*>(5000);
    Function* pre_f = va_arg(ap, Function*);
    pre_f->addToNextQs(q);
    for(int i = 0; i < count-1; i++) {
		Function* f = va_arg(ap, Function*);
        f->addToPreQs(q);
	}
    va_end(ap);
}

// 新建一个队列，多个收集到一个
void connectManyCollectOne(int count, ...){
    va_list ap;
	va_start(ap, count);
    std::vector<Function*> pre_Qs;
    for(int i = 0; i < count-1; i++) {
		Function* f = va_arg(ap, Function*);
        pre_Qs.push_back(f);
	}
    Function* the_one_f = va_arg(ap, Function*);
    BlockingQueue<Data*>* q = new BlockingQueue<Data*>(5000);
    for(auto i : pre_Qs){
        i->addToNextQs(q);
    }
    the_one_f->addToPreQs(q);
    va_end(ap);
}

// 输出某个Function的帮助信息
void help(Function* a){
    a->printSupportTypeMsg();
}

// 用于扩展某个Function的instance_number
void expand(Function* ori, int count, ...){
    va_list ap;
	va_start(ap, count);
    for(int i = 0; i < count; i++){
        Function** f = va_arg(ap, Function**);
        // 先构造一个父类的对象，再开辟空间，调用子类的构造函数
        *f = Function::Create(ori->getClassName());
        (*f)->copy(ori);
        (*f)->setPreQs(ori->getPreQs());
        (*f)->setNextQs(ori->getNextQs());
    }
    va_end(ap);
}

void expand(Function* ori_0, Function* ori_1, Function* ori_2, int count, ...){
    va_list ap;
    va_start(ap, count);
    for(int i = 0; i < count; i++){
        Function** f_0 = va_arg(ap, Function**);
        Function** f_1 = va_arg(ap, Function**);
        Function** f_2 = va_arg(ap, Function**);
        // f_0
        *f_0 = Function::Create(ori_0->getClassName());
        (*f_0)->copy(ori_0);
        (*f_0)->setPreQs(ori_0->getPreQs());
        // f_1
        *f_1 = Function::Create(ori_1->getClassName());
        (*f_1)->copy(ori_1);
        // f_2
        *f_2 = Function::Create(ori_2->getClassName());
        (*f_2)->copy(ori_2);
        (*f_2)->setNextQs(ori_2->getNextQs());
        // link
        connect(*f_0, *f_1);
        connect(*f_1, *f_2);
    }
    va_end(ap);
}

};